Jump to content
  • 0

Проблемы анимации при использовании CSS Transition и display: none/block


Anton Diaz
 Share

Question

Делал анимацию с появляющимися и исчезающими блоками через CSS Transition. Но наткнулся на проблемы. Проблему локализовал в таком коде:


<style>
#animated {
-webkit-transition: opacity 1s;
-ms-transition: opacity 1s;
-o-transition: opacity 1s;
-moz-transition: opacity 1s;
transition: opacity 1s;

padding: 1em;
border: 1px solid black;
}
</style>

<script>
function fadeIn() {
document.getElementById('animated').style.display = 'block';
document.getElementById('animated').style.opacity = '1';
}

function fadeOut() {
document.getElementById('animated').style.display = 'none';
document.getElementById('animated').style.opacity = '0';
}
</script>

<div>
<button onclick="fadeIn()">Показать</button>
<button onclick="fadeOut()">Спрятать</button>
</div>

<div id="animated">язь-два-три</div>

Как это должно работать:

1) Изначально анимируемый элемент виден

2) Когда пользователь жмет «Спрятать», изменяются два свойства: display:none, opacity:0. Конечно, здесь анимации быть не должно, так как display сработает мгновенно (элемент сразу же исключается из потока), а анимируемый opacity останется за сценой. Но здесь так и должно быть, мне так и надо.

3) Когда же пользователь жмет «Показать», обратно меняются два свойства: display:block, opacity:1. А вот здесь анимация работать должна, так как display:block работает сразу (элемент сразу же включается в поток) и opacity должен анимироваться беспрепятственно.

По логике работать должно, но в соответствии с моим описанием работают только Opera 11.6x и IE10PP5. Opera 12 (последняя тестовая сборка), Google Chrome и Firefox почему-то не хотят анимировать fadeIn.

По идее эта проблема должна быть широко известной, однако беглый гуглинг в русских Интернетах и поиск на этом форуме (привет, psywalker!) результатов не дал.

Итого, вопросы такие:

1) Почему не работает согласно описанию в большинстве браузеров? Может где-то в стандартах такое поведение предписано? Или это просто баг Хрома и Лисички, под который потом подстроилась Опера? (Помню, что-то в этом духе писали в блоге разработчиков Оперы)

2) Как же иначе можно реализовать идею, не отступая от идеи использования CSS Transition? (Анимация на чистом JS крайне медлительна)

Link to comment
Share on other sites

10 answers to this question

Recommended Posts

  • 0

2) Как же иначе можно реализовать идею, не отступая от идеи использования CSS Transition? (Анимация на чистом JS крайне медлительна)

Использовать z-index и opacity.

z-index:1 + opactiy:1 > z-index:-1 + opacity:0. Так точно будет работать.

Link to comment
Share on other sites

  • 0
2) Как же иначе можно реализовать идею, не отступая от идеи использования CSS Transition? (Анимация на чистом JS крайне медлительна)
Использовать z-index и opacity. z-index:1 + opactiy:1 > z-index:-1 + opacity:0. Так точно будет работать.

Без display:none как-то костыляво выходит. Блоки должны действительно исчезнуть (выключиться из потока), а не просто стать невидимыми. Чтобы добиться этим способом нужно результата нужно еще много чего сделать:

1) приходится переключать также position:absolute/relative

2) приходится добавлять позиционирование left:0, top: 0

3) приходится уменьшать размеры width:0, height: 0 / width:auto, height:auto, так как блоки могут оказаться крупными и увеличить размеры страницы (добавить прокрутку), даже если они прибиты к верхнему левому углу

4) приходится переключать overflow:hidden/visible, так как контент всё равно будет торчать из блока с нулевыми размерами (а оставлять overflow:hidden постоянно не комильфо, мало ли)

5) приходится отключать/включать transition (там же еще куча вариаций с префиксами!), так как при исчезновении анимация не нужна (ведь таких блоков очень много и при запуске страницы они все должны одновременно исчезнуть — большая нагрузка на железо, да и пользователь не должен видеть как они пропадают при открытии страницы)

6) и еще много подводных камней могут быть, которые сразу и не заметишь (костыли они такие)

Неужели это нельзя сделать по человечески? :(

UPD:

Ага, в подтверждение к 6-му пункту: страница притормаживает, даже если анимация сейчас не идет. А все потому, что в левом верхнем углу находятся куча невидимых, наложенных друг на друга блоков.

Edited by Anton Diaz
Link to comment
Share on other sites

  • 0

Скажем так, выдернуть блок из потока нам никто не мешает. Насчет тормозов не знаю. Надо смотреть.

p.s. там щелкать на темный блок надо, забыл сделать опознавательные знаки.

Edited by Softlink
Link to comment
Share on other sites

  • 0

Делал анимацию с появляющимися и исчезающими блоками через CSS Transition. Но наткнулся на проблемы. Проблему локализовал в таком коде:


<style>
#animated {
-webkit-transition: opacity 1s;
-ms-transition: opacity 1s;
-o-transition: opacity 1s;
-moz-transition: opacity 1s;
transition: opacity 1s;

padding: 1em;
border: 1px solid black;
}
</style>

<script>
function fadeIn() {
document.getElementById('animated').style.display = 'block';
document.getElementById('animated').style.opacity = '1';
}

function fadeOut() {
document.getElementById('animated').style.display = 'none';
document.getElementById('animated').style.opacity = '0';
}
</script>

<div>
<button onclick="fadeIn()">Показать</button>
<button onclick="fadeOut()">Спрятать</button>
</div>

<div id="animated">язь-два-три</div>

Как это должно работать:

1) Изначально анимируемый элемент виден

2) Когда пользователь жмет «Спрятать», изменяются два свойства: display:none, opacity:0. Конечно, здесь анимации быть не должно, так как display сработает мгновенно (элемент сразу же исключается из потока), а анимируемый opacity останется за сценой. Но здесь так и должно быть, мне так и надо.

3) Когда же пользователь жмет «Показать», обратно меняются два свойства: display:block, opacity:1. А вот здесь анимация работать должна, так как display:block работает сразу (элемент сразу же включается в поток) и opacity должен анимироваться беспрепятственно.

Привет! Кто тебе это сказал, что должно работать? Если ты используешь display:block - display: none, то всё, забудь про transition. Т.е. плавности тебе не видать в таком случае.

Реализовать можно, не вырубая блок вообще и убрать жс нахрен.

Link to comment
Share on other sites

  • 0

Скажем так, выдернуть блок из потока нам никто не мешает. Насчет тормозов не знаю. Надо смотреть.

p.s. там щелкать на темный блок надо, забыл сделать опознавательные знаки.

Наверное, я не так выразился. С таким вариантом элемент по-прежнему участвует в формировании страницы. Если уменьшить размеры окна (в высоту), то можно увидеть, как появляются неуместные скроллбары.

Насколько эти скроллбары неуместны можно увидеть по той странице, с которой я работаю (по поводу сообщений об ошибке на почту пока писать не нужно, это еще тестовая версия):

http://antondiaz.narod2.ru/operahelper/

Как видно, там набор блоков, которые прячутся или показываются в зависимости от ответов пользователя. В случае отключения JS будут показаны сразу все блоки и навигация будет работать за счет якорных ссылок. Так вот, если реализовать таким способом, то отображаемый контент по высоте будет занимать очень мало места, но страница будет представлять собой огромную простыню с пустотой.

Привет! Кто тебе это сказал, что должно работать? Если ты используешь display:block - display: none, то всё, забудь про transition. Т.е. плавности тебе не видать в таком случае.

Реализовать можно, не вырубая блок вообще и убрать жс нахрен.

Мне это сказала логика :) Я не вижу причин, из-за которых это работать не должно.

Что еще за жс?

Link to comment
Share on other sites

  • 0

Мне это сказала логика :) Я не вижу причин, из-за которых это работать не должно.

Что еще за жс?

По спеке вроде display: не анимируется. ЖС = JavaScript)

Да, но у меня анимироваться должен opacity, а не display. Я так и написал в пояснении о том, как это должно работать.

А без JS нельзя. Во-первых, у меня там много чего еще наворочено в нем (правда JS-кодер из меня никакой), а во-вторых, я не люблю подходы по использованию кривых CSS-методик в случаях, когда явно нужен JS. HTML — контент и структура, CSS — оформление, JS — поведение.

Link to comment
Share on other sites

  • 0

Мне это сказала логика :) Я не вижу причин, из-за которых это работать не должно.

Что еще за жс?

По спеке вроде display: не анимируется. ЖС = JavaScript)

Да, но у меня анимироваться должен opacity, а не display. Я так и написал в пояснении о том, как это должно работать.

Да, но когда ты юзаешь display, то с opacity не прокатит походу(

А без JS нельзя. Во-первых, у меня там много чего еще наворочено в нем (правда JS-кодер из меня никакой), а во-вторых, я не люблю подходы по использованию кривых CSS-методик в случаях, когда явно нужен JS. HTML — контент и структура, CSS — оформление, JS — поведение.

Если много чё наворочено уже, то и анимацию бы делал на JS.

Link to comment
Share on other sites

  • 0

Anton Diaz, добавьте задержку небольшую - http://jsfiddle.net/8vTuJ/55/

Спасибо, это то, что нужно. Проблема решена.

А без JS нельзя. Во-первых, у меня там много чего еще наворочено в нем (правда JS-кодер из меня никакой), а во-вторых, я не люблю подходы по использованию кривых CSS-методик в случаях, когда явно нужен JS. HTML — контент и структура, CSS — оформление, JS — поведение.

Если много чё наворочено уже, то и анимацию бы делал на JS.

Так и было в начале. Но отказался, так как на разном железе скорость анимации разительно отличалась от слишком быстрой и почти незаметной на 4-ядерном Core i7 с топовой видеокартой до слишком долгой (особенно для крупных блоков) на ноутбучной двухъядерной AMD E350 со встроенной графикой. Про планшеты и смартфоны вообще молчу.

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Answer this question...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

 Share

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue. See more about our Guidelines and Privacy Policy